# apps/subjects/views.py
from django.db.models import Q
from django.shortcuts import get_object_or_404
from rest_framework import viewsets, status, permissions
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from .models import Subject
from ..common.mixins import TenantViewSetMixin


class StandardResultsSetPagination(PageNumberPagination):
    page_size = 20
    page_size_query_param = 'page_size'
    max_page_size = 100

from .serializers import (
    SubjectSerializer,
    SubjectTreeSerializer,
    SubjectMinimalSerializer
)


class SubjectViewSet(TenantViewSetMixin, viewsets.ModelViewSet):
    """
    学科管理视图集
    提供完整的 CRUD 功能，并支持：
    - 树形结构展示
    - 批量启用/禁用
    - 极简列表（用于下拉选择）
    """
    queryset = Subject.objects.all().order_by('sort_order', 'level', 'name')
    serializer_class = SubjectSerializer
    permission_classes = [permissions.IsAuthenticated]  # 可根据需要调整权限
    pagination_class = StandardResultsSetPagination  # 添加这一行

    def get_serializer_class(self):
        """
        根据 action 返回不同的序列化器
        """
        if self.action == 'list_tree':
            return SubjectTreeSerializer
        elif self.action == 'minimal':
            return SubjectMinimalSerializer
        return SubjectSerializer

    def list(self, request, *args, **kwargs):
        """
        重写 list：默认返回平级列表（激活的）
        """
        queryset = self.filter_queryset(self.get_queryset()).filter(is_active=True)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=['get'], url_path='tree', url_name='list-tree')
    def list_tree(self, request):
        """
        获取学科树形结构（仅一级学科 + 其子学科）
        URL: GET /api/subjects/tree/
        """
        queryset = self.get_queryset().filter(level=1, is_active=True)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=['get'], url_path='minimal', url_name='minimal')
    def minimal(self, request):
        """
        获取极简学科列表（用于前端下拉框等）
        URL: GET /api/subjects/minimal/
        """
        queryset = self.get_queryset().filter(is_active=True)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=['post'], url_path='activate', url_name='activate')
    def activate(self, request, pk=None):
        """
        启用学科
        URL: POST /api/subjects/{id}/activate/
        """
        subject = get_object_or_404(Subject, id=pk)
        subject.is_active = True
        subject.save(update_fields=['is_active'])
        return Response({'message': f'学科 "{subject.name}" 已启用'}, status=status.HTTP_200_OK)

    @action(detail=True, methods=['post'], url_path='deactivate', url_name='deactivate')
    def deactivate(self, request, pk=None):
        """
        禁用学科
        URL: POST /api/subjects/{id}/deactivate/
        """
        subject = get_object_or_404(Subject, id=pk)
        # 禁用前检查是否有子学科正在使用（可选策略）
        if subject.children.filter(is_active=True).exists():
            return Response(
                {'error': '无法禁用：该学科下存在启用的子学科。'},
                status=status.HTTP_400_BAD_REQUEST
            )
        subject.is_active = False
        subject.save(update_fields=['is_active'])
        return Response({'message': f'学科 "{subject.name}" 已禁用'}, status=status.HTTP_200_OK)

    @action(detail=False, methods=['post'], url_path='bulk-deactivate', url_name='bulk-deactivate')
    def bulk_deactivate(self, request):
        """
        批量禁用学科
        要求：不能禁用含有子学科的学科
        """
        ids = request.data.get("ids", [])
        if not ids:
            return Response(
                {"error": "缺少学科ID列表"},
                status=status.HTTP_400_BAD_REQUEST
            )

        try:
            subjects = Subject.objects.filter(id__in=ids)
            invalid_subjects = []

            # 检查每个要禁用的学科是否有子学科
            for subject in subjects:
                if subject.has_children():
                    invalid_subjects.append(subject.name)

            if invalid_subjects:
                return Response(
                    {"error": f"以下学科存在子学科，无法禁用：{', '.join(invalid_subjects)}"},
                    status=status.HTTP_400_BAD_REQUEST
                )

            # 安全地批量更新
            count = subjects.update(is_active=False)

            return Response({
                "message": f"成功禁用 {count} 个学科"
            }, status=status.HTTP_200_OK)

        except Exception as e:
            return Response(
                {"error": "操作失败：" + str(e)},
                status=status.HTTP_400_BAD_REQUEST
            )

    @action(detail=False, methods=['get'], url_path='search', url_name='search')
    def search(self, request):
        """
        按名称或编码搜索学科（激活的）
        支持参数: q=数学
        URL: GET /api/subjects/search/?q=数学
        """
        query = request.query_params.get('q', '').strip()
        if not query:
            return Response([], status=status.HTTP_200_OK)

        subjects = Subject.objects.filter(
            is_active=True
        ).filter(
            Q(name__icontains=query) | Q(code__icontains=query)
        ).order_by('sort_order', 'name')

        page = self.paginate_queryset(subjects)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(subjects, many=True)
        return Response(serializer.data)